<template>
  <div class="blast-container">
    <el-card class="blast-card">
      <!-- 页面标题 -->
      <div class="page-header">
        <h1>菌物药种质资源库序列检索工具</h1>
      </div>

      <!-- 上下分栏布局 -->
      <div class="vertical-layout">
        <!-- 上方：输入区域 -->
        <div class="input-section">
          <h2 class="section-title">序列输入</h2>

          <el-form :model="form" label-width="120px" class="blast-form" ref="blastForm">
            <!-- 新增说明文字 -->
            <el-form-item>
              <div class="input-instructions">
                <p>基于菌物药种质资源库的DNA序列信息，输入DNA序列进行比对鉴定。</p>
              </div>
            </el-form-item>

            <!-- E值 -->
            <el-form-item
                label="E-value"
                prop="evalue"
                :rules="[
                          { required: true, message: '请输入E-value' },
                          { validator: validateEvalue, trigger: 'blur' }
                        ]"
            >
              <el-input
                  v-model="form.evalue"
                  style="width: 120px;"
              />
            </el-form-item>

            <!-- 序列输入 -->
            <el-form-item label="输入序列" class="sequence-input-item">
              <div class="input-container">
                <el-input
                    v-model="form.fasta"
                    clearable
                    type="textarea"
                    :rows="8"
                    :placeholder="fastaPlaceholder"
                    resize="none"
                    style="width: 80%; font-family: monospace;"
                    @dblclick="form.fasta = fastaPlaceholder"
                />
                <div class="input-hint">
                  <span>双击输入框自动填充示例</span>
                </div>
              </div>
            </el-form-item>



            <!-- 文件上传 -->
            <el-form-item label="文件上传">
              <el-upload
                  action=""
                  :auto-upload="false"
                  :show-file-list="false"
                  :on-change="handleFileUpload"
                  accept=".fas,.fasta,.fa,.FAS,.FASTA,.FA"
              >
                <el-button>选择文件</el-button>
                <span v-if="uploadedFileName" style="margin-left: 10px;">{{ uploadedFileName }}</span>
              </el-upload>
              <div style="font-size: 12px; color: #909399; margin-top: 5px; margin-left: 20px;">
                只能上传FAS、FASTA、FA格式的文件(不区分大小写)
              </div>
            </el-form-item>
            <!-- 按钮区域 -->
            <el-form-item>
              <el-button @click="handleReset">重置</el-button>
              <el-button @click="handleSubmit">提交</el-button>
            </el-form-item>
          </el-form>
        </div>

        <!-- 下方：结果区域 -->
        <div class="result-section">
          <h2 class="section-title">比对结果</h2>

          <div class="result-container">
            <!-- 结果状态提示 -->
            <div class="result-status" v-if="!showResults">
              <el-empty description="请输入序列并提交搜索" />
            </div>

            <!-- 加载状态 -->
            <div class="result-status" v-if="isLoading">
              <el-icon class="is-loading" style="font-size: 50px; color: #409eff;">
                <Loading />
              </el-icon>
              <div style="margin-top: 10px;">搜索中...</div>
            </div>

            <!-- 结果表格 -->
            <div class="result-content" v-else-if="results.length">
              <el-table
                  :data="paginatedResults"
                  border
                  style="width: 100%"
                  highlight-current-row
              >
                <el-table-column prop="key" label="key" width="150" fixed/>
                <el-table-column prop="status" label="status" width="150" />
                <el-table-column prop="id" label="id" width="150" />
                <el-table-column prop="strain_number" label="strain_number" width="150" />
                <el-table-column prop="preservation_number" label="preservation_number" width="150" />
                <el-table-column prop="family_name" label="family_name" width="150" />
                <el-table-column prop="genus_name" label="genus_name" width="150" />
                <el-table-column prop="species_name" label="species_name" width="180" />
                <el-table-column prop="chinese_latin_species_name" label="chinese_latin_species_name" width="150" />
                <el-table-column prop="collection_location" label="collection_location" width="120" />
                <el-table-column prop="isolation_source" label="isolation_source" width="150" />
                <el-table-column prop="collector" label="collector" width="150" />
                <el-table-column prop="isolation_date" label="isolation_date" width="120" />
                <el-table-column prop="strain_function" label="strain_function" width="150" />
                <el-table-column prop="reference_sequence" label="reference_sequence" width="150" show-overflow-tooltip/>
                <el-table-column prop="reference_genome" label="reference_genome" width="150" show-overflow-tooltip/>
                <el-table-column prop="ncbi_similar_strain" label="ncbi_similar_strain" width="150" show-overflow-tooltip/>
                <el-table-column prop="ncbi_accession_number" label="ncbi_accession_number" width="150" />
                <el-table-column prop="similarity_ncbi" label="similarity_ncbi" width="100" align="center" />
                <el-table-column prop="ez_similar_strain" label="ez_similar_strain" width="150"show-overflow-tooltip />
                <el-table-column prop="ez_accession_number" label="ez_accession_number" width="150" />
                <el-table-column prop="similarity_ez" label="similarity_ez" width="100" align="center" />
                <el-table-column prop="maintenance_date" label="maintenance_date" width="120" />
              </el-table>

              <!-- 分页控件 -->
              <el-pagination
                  @size-change="handleSizeChange"
                  @current-change="handleCurrentChange"
                  :current-page="currentPage"
                  :page-sizes="[5, 10, 20]"
                  :page-size="pageSize"
                  layout="total, sizes, prev, pager, next, jumper"
                  :total="results.length"
                  style="margin-top: 20px;"
              ></el-pagination>
            </div>

            <!-- 无结果提示 -->
            <div class="result-content" v-else-if="showResults">
              <el-empty description="未找到匹配结果" />
            </div>
          </div>
        </div>
      </div>
    </el-card>

    <el-dialog
        v-model="resultDialogVisible"
        :title="resultDialogTitle"
        width="30%"
    >
      <span>{{ resultDialogMessage }}</span>
      <template #footer>
        <el-button @click="resultDialogVisible = false">OK</el-button>
      </template>
    </el-dialog>

  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, computed } from 'vue';
import { Loading } from '@element-plus/icons-vue';
import { BlastForm } from '~/types/blast'
import {blastTask} from "~/api/blastApi";

// 定义结果项类型
interface BlastResult {
  // 菌株信息
  key: string;
  status: string;
  id: number | null;
  strain_number: string | null;
  preservation_number: string | null;
  family_name: string | null;
  genus_name: string | null;
  species_name: string | null;
  chinese_latin_species_name: string | null;
  collection_location: string | null;
  isolation_source: string | null;
  collector: string | null;
  isolation_date: string | null;
  strain_function: string | null;
  reference_sequence: string | null;
  reference_genome: string | null;
  ncbi_similar_strain: string | null;
  ncbi_accession_number: string | null;
  similarity_ncbi: number | null;
  ez_similar_strain: string | null;
  ez_accession_number: string | null;
  similarity_ez: number | null;
  maintenance_date: string | null;
}

// 表单数据
const form = reactive<BlastForm>({
  evalue: 0.00001,
  fasta: '',
  fasta_file: null
});

const uploadedFileName = ref<string>('');

// 序列输入框的占位文本
const fastaPlaceholder = `>hhhhdsad
CTACCATGCAAGTCGAGCGCCCCGCAAGGGGAGCGGCAGACGGGT
GAGTAACGCGTGGGAATCTACCCTTTTCTACGGAATAACGCAGGG
AAACTTGTGCTAATACCGTATGTGTCCTTCGGGAGAAAGATTTAT
CGGGAAAGGATGAGCCCGCGTTGGATTAGCTAGTTGGTGGGGTAA`;


// 结果相关
const showResults = ref<boolean>(false);
const isLoading = ref<boolean>(false);
const results = ref<BlastResult[]>([]);
const currentPage = ref<number>(1);
const pageSize = ref<number>(10);

const resultDialogVisible = ref(false)
const resultDialogTitle = ref('')
const resultDialogMessage = ref('')

// 计算分页后的结果
const paginatedResults = computed<BlastResult[]>(() => {
  const start = (currentPage.value - 1) * pageSize.value;
  const end = start + pageSize.value;
  return results.value.slice(start, end);
});

// 处理文件上传
const handleFileUpload = (file: any): void => {
  uploadedFileName.value = file.name;
  const reader = new FileReader();
  reader.onload = (e: ProgressEvent<FileReader>) => {
    if (e.target?.result) {
      form.fasta = e.target.result as string;
    }
  };
  reader.readAsText(file.raw);
};

// 重置表单
const handleReset = (): void => {
  form.evalue = 0.00001;
  form.fasta = '';
  form.fasta_file = null;
  uploadedFileName.value = '';
  showResults.value = false;
  results.value = [];
  currentPage.value = 1;
};

// 提交搜索
const handleSubmit = async () => {
  if (!form.fasta.trim()) {
    showResultDialog(false, '请输入序列！')
    return;
  }

  // 显示加载状态
  isLoading.value = true;
  showResults.value = true;

  try {
    const formData = new FormData();
    formData.append('evalue', form.evalue.toString()); // 直接访问属性


    if (form.fasta_file) {
      formData.append('fasta_file', form.fasta_file); // 直接访问属性
    }
    if (form.fasta) {
      formData.append('fasta', form.fasta);
    }

    const response = await blastTask(formData);

    if (response.success) {

      results.value = [];
      for (const [key, item] of Object.entries(response.data)) {

        let resultItem: BlastResult;

        if (item) {
          const strainInfo = item.strain_info;
          resultItem = {
            key: key,
            status: '已匹配',
            id: strainInfo.id,
            strain_number: strainInfo.strain_number,
            preservation_number: strainInfo.preservation_number,
            family_name: strainInfo.family_name,
            genus_name: strainInfo.genus_name,
            species_name: strainInfo.species_name,
            chinese_latin_species_name: strainInfo.chinese_latin_species_name,
            collection_location: strainInfo.collection_location,
            isolation_source: strainInfo.isolation_source,
            collector: strainInfo.collector,
            isolation_date: strainInfo.isolation_date,
            strain_function: strainInfo.strain_function,
            reference_sequence: strainInfo.reference_sequence,
            reference_genome: strainInfo.reference_genome,
            ncbi_similar_strain: strainInfo.ncbi_similar_strain,
            ncbi_accession_number: strainInfo.ncbi_accession_number,
            similarity_ncbi: strainInfo.similarity_ncbi,
            ez_similar_strain: strainInfo.ez_similar_strain,
            ez_accession_number: strainInfo.ez_accession_number,
            similarity_ez: strainInfo.similarity_ez,
            maintenance_date: strainInfo.maintenance_date
          }
        } else {
          resultItem = {
            key: key,
            status: '未匹配',
            id: null,
            strain_number: null,
            preservation_number: null,
            family_name: null,
            genus_name: null,
            species_name: null,
            chinese_latin_species_name: null,
            collection_location: null,
            isolation_source: null,
            collector: null,
            isolation_date: null,
            strain_function: null,
            reference_sequence: null,
            reference_genome: null,
            ncbi_similar_strain: null,
            ncbi_accession_number: null,
            similarity_ncbi: null,
            ez_similar_strain: null,
            ez_accession_number: null,
            similarity_ez: null,
            maintenance_date: null
          }

        }
        results.value.push(resultItem);
      }

      showResultDialog(response.success, response.msg)

    } else {
      results.value = [];
      showResultDialog(false, response.error)
    }
  } catch (error) {
    showResultDialog(false, 'Identification failed')
    results.value = [];
  } finally {
    isLoading.value = false;
  }};

const showResultDialog = (isSuccess: boolean, message: string) => {
  resultDialogTitle.value = isSuccess ? 'Success' : 'Error'
  resultDialogMessage.value = message
  resultDialogVisible.value = true
}

// 分页相关方法
const handleSizeChange = (newSize: number): void => {
  pageSize.value = newSize;
  currentPage.value = 1;
};

const handleCurrentChange = (newPage: number): void => {
  currentPage.value = newPage;
};

// E-value校验方法
const validateEvalue = (rule: any, value: any, callback: any) => {
  const evalueRegex = /^[0-9]*\.?[0-9]+$/;
  if (!evalueRegex.test(value)) {
    callback(new Error('E-value必须为数字'));
  } else {
    callback();
  }
};

</script>



<style scoped>
.blast-container {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}

.blast-card {
  width: 100%;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.page-header {
  padding: 20px;
  border-bottom: 1px solid #ebeef5;
}

.page-header h1 {
  color: #303133;
  font-size: 28px;
  margin: 0;
  text-align: center;
}

.vertical-layout {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 20px;
}

.input-section {
  padding-bottom: 20px;
  border-bottom: 1px solid #ebeef5;
}

.result-section {
  padding-top: 20px;
}

.section-title {
  color: #303133;
  font-size: 22px;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ebeef5;
}

.blast-form {
  margin-top: 20px;
}

.input-instructions {
  margin-top: 10px;
  padding: 10px;
  background-color: #f8f9fa;
  border-radius: 4px;
  border-left: 4px solid #409eff;
  color: #606266;
}

.input-instructions p {
  margin: 5px 0;
  font-size: 14px;
}

/* 序列输入容器样式 */
.sequence-input-item .el-form-item__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start; /* 保持左对齐 */
}

.input-container {
  width: 100%;
  display: flex;
  flex-direction: column;
}

.input-hint {
  font-size: 12px;
  color: #909399;
  display: flex;
  align-items: flex-start;
}

.result-container {
  min-height: 500px;
  position: relative;
}

.result-status {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: rgba(255, 255, 255, 0.8);
}

.result-content {
  min-height: 500px;
}

/* 按钮样式调整 */
.el-button {
  margin-right: 10px;
  min-width: 100px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .blast-form :deep(.el-form-item__label) {
    text-align: left;
    margin-bottom: 5px;
  }

  .blast-form :deep(.el-form-item__content) {
    margin-left: 0 !important;
  }

  .el-button {
    width: 100%;
    margin-bottom: 10px;
  }
}
</style>